<?php

class Authentication_Exception extends CMS_Exception {}
class Authentication_Credentials_Exception extends Authentication_Exception {}

class Authentication {

	protected static $instance;
	protected $user;

	protected static $credential_systems = array();

	public static function getInstance(){
		if(!isset(Authentication::$instance)){
			Authentication::$instance = new Authentication;
		}
		return Authentication::$instance;
	}

	protected function __construct(){
		if(session_id() == ""){
			session_start();
		}
	}

	public function authenticate($credentials){
		foreach(Authentication::$credential_systems as $system){
			try {
				$this->user = $system->authenticate($credentials);
				$_SESSION['user'] = $this->user->id();
				return $this->user;
			} catch(Exception $e){}
		}
		throw new Authentication_Credentials_Exception();
	}

	public static function Credentials($system){
		Authentication::$credential_systems[] = $system;
	}

	public function user(){
		if(isset($this->user)){
			return $this->user;
		}
		try {
			if(isset($_SESSION['user'])){
				$this->user = User::GetByID($_SESSION['user']);
				return $this->user;
			}
		} catch(Exception $e){}
		$this->user = new User_Guest();
		return $this->user;
	}

}

abstract class Authentication_Credentials {
	abstract function authenticate($credentials);
}
